/**
 *
 */
package com.newer.config.shiro.bean;

import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

/**
 * SpringShiro过滤配置
 *
 * @author xuntj
 * @create 2018-03-14 11:27
 **/
public class MySpringShiroFilter extends AbstractShiroFilter {

    // 对ShiroFilter来说，需要直接忽略的请求
    private static Set<String> ignoreExt;

    /**
     * 默认数据过滤列表
     */
    static {
        ignoreExt = new HashSet<>();
        ignoreExt.add(".jpg");
        ignoreExt.add(".png");
        ignoreExt.add(".gif");
        ignoreExt.add(".bmp");
        ignoreExt.add(".js");
        ignoreExt.add(".css");
        ignoreExt.add(".ttf");
        ignoreExt.add(".woff");
        ignoreExt.add(".woff2");
        ignoreExt.add(".svg");
        ignoreExt.add(".eot");
        ignoreExt.add(".txt");
        ignoreExt.add(".json");
    }

    /**
     * 构造方法
     *
     * @param webSecurityManager
     * @param resolver
     */
    protected MySpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
        super();
        if (webSecurityManager == null) {
            throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
        }
        setSecurityManager(webSecurityManager);
        if (resolver != null) {
            setFilterChainResolver(resolver);
        }
    }

    /**
     * 过滤方法
     *
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse,
                                    FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String str = request.getRequestURI().toLowerCase();
        // 因为ShiroFilter 拦截所有请求（在上面我们配置了urlPattern 为，
        // 当然你也可以在那里精确的添加要处理的路径，这样就不需要这个类了），
        // 而在每次请求里面都做了session的读取和更新访问时间等操作，这样在集群部署session共享的情况下，
        // 数量级的加大了处理量负载。所以我们这里将一些能忽略的请求忽略掉。
        // 当然如果你的集群系统使用了动静分离处理，静态资料的请求不会到Filter这个层面，便可以忽略。
        boolean flag = true;
        int idx = 0;
        if ((idx = str.lastIndexOf(".")) > 0) {
            str = str.substring(idx);
            if (ignoreExt.contains(str.toLowerCase())) {
                flag = false;
            }
        }
        if (flag) {
            super.doFilterInternal(servletRequest, servletResponse, chain);
        } else {
            chain.doFilter(servletRequest, servletResponse);
        }
    }
}
